// FIT_6204_Gorodilov_GreedyDoc.h : interface of the CFIT_6204_Gorodilov_GreedyDoc class
//


#pragma once
#include "atltypes.h"

typedef struct {
	UINT a;
	UINT b;
} EDGE;

typedef struct{
	UINT N;
	double L;
	double T;
	double LG;
	double TG;
	int type;
} LOGENTRY;


typedef struct {
	UINT vert[3];
	UINT trg[3];
	UINT edge[3];
} TRIANGLE;

#define EPS 1e-15

class CFIT_6204_Gorodilov_GreedyDoc : public CDocument
{
protected: // create from serialization only
	CFIT_6204_Gorodilov_GreedyDoc();
	DECLARE_DYNCREATE(CFIT_6204_Gorodilov_GreedyDoc)

// Attributes
public:

// Operations
public:

// Overrides
public:
	virtual BOOL OnNewDocument();
	virtual void Serialize(CArchive& ar);

// Implementation
public:
	virtual ~CFIT_6204_Gorodilov_GreedyDoc();
#ifdef _DEBUG
	virtual void AssertValid() const;
	virtual void Dump(CDumpContext& dc) const;
#endif

protected:

// Generated message map functions
protected:
	DECLARE_MESSAGE_MAP()
public:
	CArray<CPoint> m_Points;
	CArray<EDGE> m_Edges;
	CArray<EDGE> m_EdgesDelaunay;
	CArray<EDGE> m_EdgesDelaunayF;
	CArray<TRIANGLE> m_Triangles;
	CArray<int> m_TrianglesI;
	CSize m_ScrollSize;
	BOOL m_IsTriangulationReady;
	BOOL m_IsTriangulationDelaunayReady;
	BOOL m_IsTriangulationDelaunayReadyF;
	CArray<LOGENTRY> m_Log;
	UINT uFirstPoint;
	CPoint firstPoint;
	UINT* m_pCache;
	UINT m_uCacheSize;

public:
	const CSize GetScrollSize(void) const;
	void SetScrollSize(const CSize scrollSize);

	const CPoint GetPoint(const UINT index);
	const UINT GetCount(void);
	const EDGE GetEdge(const UINT index);
	const UINT GetEdgesCount(void);
	const EDGE GetEdgeDelaunay(const UINT index);
	const UINT GetEdgesDelaunayCount(void);
	const EDGE GetEdgeDelaunayF(const UINT index);
	const UINT GetEdgesDelaunayCountF(void);
	BOOL UpdatePoint(UINT index, const CPoint point);
	UINT PeekPoint(const CPoint point, int distance);
	UINT AddPoint(const CPoint point);
	void DeletePoint(const CPoint point, int distance);
	double MakeGreedyTriangulation(void);
	BOOL IsTriangulationReady(void);
	BOOL IsTriangulationDelaunayReady(void);
	BOOL IsTriangulationDelaunayReadyF(void);
	BOOL Log(UINT N, double L, double T, int type, double LD = 0.0, double TD = 0.0);
	BOOL SaveLog(CString filePath);
	BOOL Shuffle(void);
	double MakeDelaunayTriangulation(void);
	double MakeDelaunayTriangulationF(void);

public: 
	const double GetEdgeLenght(const CPoint &a, const CPoint &b);
	BOOL IsEdgeCrossEdge(EDGE &edge1, EDGE &edge2);
	BOOL TestEdge(EDGE &edge1);
	BOOL IsDelaunay(const TRIANGLE trg, const TRIANGLE trg2);
	BOOL IsDelaunay(const TRIANGLE trg, const CPoint p01);
};

static CFIT_6204_Gorodilov_GreedyDoc *g_pDoc = NULL;
int compareAngle( const void *arg1, const void *arg2 );
int compareEdges( const void *arg1, const void *arg2 );
BOOL IsLinesCross(UINT x1, UINT y1, UINT x2, UINT y2,
			 UINT x3, UINT y3, UINT x4, UINT y4);

BOOL IsPointInsideTriangle(const CPoint p1, const CPoint p2, const CPoint p3,
						   const CPoint point);
double Square(const CPoint p1, const CPoint p2, const CPoint p3);
BOOL IsPointOppositeEdge(const CPoint p1, const CPoint e1, const CPoint e2, const CPoint target);

CString GetNextLine(CArchive& ar);